/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
#include "data_log.h"
#include <time.h>

#ifdef SQL_LIBS
int sql_query_log(struct probe_descriptor probe[],struct configuration_struct *settings,char iso_time[]) {
/* build and send an sql query to the sql server in order to log data fro ALL probes */
/* return EXIT_SUCCESS or EXIT_FAILURE */
/* we need to build a string like 'INSERT into table (field1,field2) values (value1,value2)' */
	int number,probe_index;
	
	/* building the SQL query */
	sql_query_into[0]='\0';
	sql_query_values[0]='\0';
	for(probe_index=0;probe_index<settings->num_probes;probe_index++) {
		/* building the list of sql fields where to write */
		number=snprintf(sql_query,(size_t)(SQL_QUERY_LENGHT*sizeof(char)),"%s%d,",settings->sql_field,probe_index+1);
		if(number <= -1 || number >= (int)(SQL_QUERY_LENGHT*sizeof(char))) {
			error_log(_("sql_query_log: query string building failure (increase SQL_QUERY_LENGHT?)\n"));
			return EXIT_FAILURE;
		}
		strncat(sql_query_into,sql_query,SQL_QUERY_LENGHT);
		/* building the list of sql values */
		number=snprintf(sql_query,(size_t)(SQL_QUERY_LENGHT*sizeof(char)),"%g,",probe[probe_index].value*probe[probe_index].conv2rh);
		if(number <= -1 || number >= (int)(SQL_QUERY_LENGHT*sizeof(char))) {
			error_log(_("sql_query_log: query string building failure (increase SQL_QUERY_LENGHT?)\n"));
			return EXIT_FAILURE;
		}
		strncat(sql_query_values,sql_query,SQL_QUERY_LENGHT);
	}
	number=snprintf(sql_query,(size_t)(SQL_QUERY_LENGHT*sizeof(char)),"INSERT into %s (%stimestamps) values (%s'%s')",settings->sql_table,sql_query_into,sql_query_values,iso_time);
	#ifdef DEBUG
		printf("Query=%s\n",sql_query);
	#endif
	if(number <= -1 || number >= (int)(SQL_QUERY_LENGHT*sizeof(char))) {
		error_log(_("sql_query_log: final query string building failure (increase SQL_QUERY_LENGHT?)\n"));
		return EXIT_FAILURE;
	}
	
	/* submitting the SQL query */
	/* checking that the database is still there and if not, trying to reconnect */
	if(mysql_ping(&settings->mysql)){
		error_log(_("Trying to reconnect to the database...\n"));
		#ifdef DEBUG
			error_log("\tClosing the current database connection.\n");
		#endif
		mysql_close(&settings->mysql);
		#ifdef DEBUG
			error_log("\tRe-initializing database connection.\n");
		#endif
		if(sql_init(settings)== EXIT_FAILURE) {
			return EXIT_FAILURE;
		}
		#ifdef DEBUG
			error_log("\tDatabase connection successfully restarted !\n");
		#endif
		return EXIT_FAILURE;
	}
	
	if(mysql_query(&settings->mysql,sql_query))
	{
		fprintf(stderr,_("Query \"%s\" failed for %s@%s (%s)\n"),sql_query,settings->sql_user,settings->sql_host,mysql_error(&settings->mysql));
		if(syslog_flag==EXIT_SUCCESS) syslog(LOG_ERR,_("Query \"%s\" failed for %s@%s (%s)\n"),sql_query,settings->sql_user,settings->sql_host,mysql_error(&settings->mysql));
		return EXIT_FAILURE;
	}
	
	return EXIT_SUCCESS;
}
#endif

int screen_log(struct probe_descriptor probe[],struct configuration_struct *settings,char iso_time[]) {
/* write data to the screen */
/* return EXIT_SUCCESS or EXIT_FAILURE */
	int probe_index;

	printf("%s\n",iso_time);
	for(probe_index=0;probe_index<settings->num_probes;probe_index++) {
		printf("\t[%d] -> %4g [%s]\t%1.3g [%s]\n",probe[probe_index].index,probe[probe_index].value*probe[probe_index].conv2display,probe[probe_index].display_units,probe[probe_index].value*probe[probe_index].conv2rh,probe[probe_index].si_units);
	}
	return EXIT_SUCCESS;
}

int file_log(struct probe_descriptor probe[],struct configuration_struct *settings,char iso_time[]) {
/* write data to the log file */
/* return EXIT_SUCCESS or EXIT_FAILURE */
	int probe_index;

	for(probe_index=0;probe_index<settings->num_probes;probe_index++) {
		if(probe[probe_index].log_file!=NULL) {
		/* If file logging has been disabled for some probes, then log_file is NULL */
			if (fprintf(probe[probe_index].log_file,"%s %4g %g\n",iso_time,probe[probe_index].value*probe[probe_index].conv2display,probe[probe_index].value*probe[probe_index].conv2rh) <= 0) {
				error_log(_("file_log: error while writing to the log file\n"));
				return EXIT_FAILURE;
			}
			#ifdef DEBUG
				printf("Wrote to log file[%d]: \"%s %4g %g\"\n",probe[probe_index].index,iso_time,probe[probe_index].value*probe[probe_index].conv2display,probe[probe_index].value*probe[probe_index].conv2rh);
			#endif
		}
	}
	return EXIT_SUCCESS;
}


int data_log(struct probe_descriptor probe[],struct configuration_struct *settings) {
/* called by the timer (SIGALRM), write the cpm and dose for every probes */
/* return EXIT_SUCCESS or EXIT_FAILURE */
	struct tm *local_time;			/* local time structure */
	char iso_time[20];			/* string containing the ISO formated time */
	time_t timing;				/* time in seconds since EPOC */
	int probe_index;
	
	/* building the time string */
	if(time(&timing) == ((time_t)-1)) {
		error_log(_("data_log: Time reading failure - skipping event\n"));
		return EXIT_FAILURE;
	}
	if((local_time=(struct tm*)localtime(&timing)) != NULL) { /* cast done because gcc was complaining. Why??? */
		strftime(iso_time,(size_t)20,"%Y-%m-%d-%H:%M:%S",(struct tm*)localtime(&timing));
	} else {
		error_log(_("data_log: Time conversion failure"));
		return EXIT_FAILURE;
	}
	
	/* logging the data */
	screen_log(probe,settings,iso_time);
	#ifdef SQL_LIBS
	if(settings->sql_log==EXIT_SUCCESS) sql_query_log(probe,settings,iso_time);
	#endif
	if(settings->file_log==EXIT_SUCCESS) file_log(probe,settings,iso_time);
	
	/* reset the counter in CPM mode */
	if (settings->pulse_mode!=EXIT_SUCCESS) {
		for (probe_index=0;probe_index<settings->num_probes;probe_index++) probe[probe_index].value=0;
	}
	return EXIT_SUCCESS;
}

void error_log(char error_string[]) {
/* error logging: write to stderr and/or to syslog */
/* nothing to return, we are already in an error processing function ! */
	perror(error_string);
	if(syslog_flag==EXIT_SUCCESS) syslog(LOG_ERR,error_string);

}
